capture log close
log using wc_analysis, replace text
//program:  wc_analysis.do
//task:     Analysis, tables & figures   
//project:  Welfare Chauvinism CES survey experiment    
//author: Jake Haselswerdt \ 2025-2-18

//program setup
version 18
clear all
set linesize 80
macro drop _all
set scheme s1color
set more off

use WC_CES23.dta, clear

//General welfare chauvinism hypothesis: Americans will be more supportive of a candidate that favors expanding social welfare programs and restricting eligibility for these programs to exclude immigrants than they will be to support a candidate who only favors one of these changes. 
reg votelikely i.expansion##i.tightening, robust /*For regression table*/
est sto main
reg votelikely i.wctreat, robust /*For figure*/
lincom _b[2.wctreat]-_b[4.wctreat] /*Support specifically higher in the expansion group*/
margins, over(wctreat)
marginsplot, recast(scatter) title("") ylabel(2(1)4) ymtick(2(.5)4) xscale(r(.6 4.4)) xtitle("") ytitle(Likelihood of voting for candidate (1-5, SD=1.2))
gr export Figures/gen.png, as(png) replace /*Figure 1*/

//Educational welfare chauvinism hypothesis: Compared to more educated Americans, less educated Americans will be more supportive of a candidate that that favors expanding social welfare programs and restricting eligibility for these programs to exclude immigrants over a candidate who only favors one of these changes (the positive interaction effect of these two positions will be larger for less educated Americans). 
reg votelikely i.expansion##i.tightening##c.educ, robust
est tab, p(%12.10g)
est sto educ
margins, dydx(expansion) over(tightening) at(educ=(1(1)6))
marginsplot, title("") ytitle(Effect of welfare expansion treatment on vote likelihood) ylabel(-1(.25).5) yline(0, lpattern(dot) lcolor(gs10)) ylabel(-2(1)2) ymtick(-2(.5)2) title("")recast(line) recastci(rarea) ci1opts(fcolor(%30)) ci2opts(fcolor(%30)) xtitle("") xlabel(, labsize(medsmall))  graphregion(margin(l+5 r+5)) legend(pos(6) ring(0))
gr export Figures/educ_dydx_expansion.png, as(png) replace /*Figure 2*/

//Ideological welfare chauvinism hypothesis: Compared to more liberal Americans, more conservative Americans will be more supportive of a candidate that that favors expanding social welfare programs and restricting eligibility for these programs to exclude immigrants over a candidate who only favors one of these changes (the positive interaction effect of these two positions will be larger for more conservative Americans).
//Traditional welfare ideology hypothesis: Compared to more liberal Americans, more conservative Americans will be less supportive of a candidate that favors expanding social welfare programs regardless of whether the candidate also supports restricting eligibility for these programs to exclude immigrants.  
reg votelikely i.expansion##i.tightening##c.ideology, robust
est tab, p(%12.10g) 
est sto ideo
margins, dydx(expansion) over(tightening) at(ideology=(1(1)5))
marginsplot, yline(0, lpattern(dot) lcolor(gs10)) ytitle(Effect of welfare expansion treatment on vote likelihood) ylabel(-2(1)2) ymtick(-2(.5)2) xtitle("") xlabel(, labsize(medsmall)) graphregion(margin(l+8 r+8)) recast(line) recastci(rarea) ci1opts(fcolor(%30)) ci2opts(fcolor(%30)) title("") legend(pos(6) ring(0)) 
gr export Figures/ideo_dydx_expansion.png, as(png) replace /*Figure 3*/

//Appendix C. Results Tables with and Without Sampling Weights.

*Without weights (main results) - Table C1
esttab main educ ideo using Tables/maintable, b(2) se(2) onecell star(* .1 ** .05 *** .01) r2 tab label interaction(" X ") nomtitles nobaselevels replace

*With weights - Table C2
reg votelikely i.expansion##i.tightening [pw=teamweight]
est sto mainweight
reg votelikely i.expansion##i.tightening##c.educ [pw=teamweight]
est sto educweight
reg votelikely i.expansion##i.tightening##c.ideology [pw=teamweight]
est sto ideoweight
esttab mainweight educweight ideoweight using Tables/maintable_weights, b(2) se(2) onecell star(* .1 ** .05 *** .01) r2 tab label interaction(" X ") nomtitles nobaselevels replace


//Appendix D. Pre-Registered Exploratory Analyses and Alternative Specifications.

*Replacing ordinal education measure with categorical indicators
reg votelikely i.expansion##i.tightening##i.educ, robust
est sto educ_nl
margins, dydx(expansion) over(tightening) at(educ=(1(1)6))
marginsplot, yline(0, lpattern(dot) lcolor(gs10)) ylabel(-2(1)2) ymtick(-2(.5)2) ytitle(Effect of welfare expansion treatment on vote likelihood) xtitle("") xlabel(, labsize(medsmall)) graphregion(margin(l+5 r+5)) title("") legend(pos(6) ring(0))
gr export Figures/educ_nl_dydx_expansion.png, as(png) replace /*Figure D1*/

esttab educ_nl using Tables/educ_nl, b(2) se(2) onecell star(* .1 ** .05 *** .01) r2 tab label interaction(" X ") nomtitles nobaselevels replace /*Table D1*/

*Replacing ordinal ideology measure with categorical indicators
reg votelikely i.expansion##i.tightening##b3.ideology, robust
est sto ideology_nl
margins, dydx(expansion) over(ideology tightening)
marginsplot, yline(0, lpattern(dot) lcolor(gs10)) ylabel(-2(1)2) ymtick(-2(.5)2) ytitle(Effect of welfare expansion treatment on vote likelihood) xtitle("") xlabel(, labsize(medsmall)) graphregion(margin(l+8 r+8)) title("") legend(pos(6) ring(0))
gr export Figures/ideo_nl_dydx_expansion.png, as(png) replace /*Figure D2*/

esttab ideology_nl using Tables/ideology_nl, b(2) se(2) onecell star(* .1 ** .05 *** .01) r2 tab label interaction(" X ") nomtitles nobaselevels replace /*Table D2*/

*Replacing education with political knowledge and income (two models)
reg votelikely i.expansion##i.tightening##c.polknow, robust
est sto polknow
margins, dydx(expansion) over(tightening) at(polknow=(0(1)8))
marginsplot, title("") ytitle(Effect of welfare expansion treatment on vote likelihood) ylabel(-1(.25).5) yline(0, lpattern(dot) lcolor(gs10)) ylabel(-2(1)2) ymtick(-2(.5)2) title("")recast(line) recastci(rarea) ci1opts(fcolor(%30)) ci2opts(fcolor(%30)) xlabel(, labsize(medsmall)) graphregion(margin(l+5 r+5)) legend(pos(6) ring(0)) saving(Figures/polknow.gph, replace)

reg votelikely i.expansion##i.tightening##c.faminc_clean, robust 
est sto faminc
margins, dydx(expansion) over(tightening) at(faminc_clean=(1(1)12)) /*95th percentile value*/
marginsplot, title("") ytitle(Effect of welfare expansion treatment on vote likelihood) ylabel(-1(.25).5) yline(0, lpattern(dot) lcolor(gs10)) ylabel(-2(1)2) ymtick(-2(.5)2) title("")recast(line) recastci(rarea) ci1opts(fcolor(%30)) ci2opts(fcolor(%30)) xlabel(1 6 12, labsize(small)) xmtick(1(1)12) graphregion(margin(l+10 r+10)) legend(pos(6) ring(0)) saving(Figures/faminc.gph, replace)

esttab polknow faminc using Tables/polknow_faminc, b(2) se(2) onecell star(* .1 ** .05 *** .01) r2 tab label interaction(" X ") nomtitles nobaselevels replace /*Table D3*/

grc1leg Figures/polknow.gph Figures/faminc.gph
gr export Figures/polknow_faminc.png, replace /*Figure D3*/

*Replacing ideology with partisanship and anti-immigration policy scale (two models)
reg votelikely i.expansion##i.tightening##c.pid7_clean, robust
est sto pid7
margins, dydx(expansion) over(tightening) at(pid7_clean=(1(1)7))
marginsplot, yline(0, lpattern(dot) lcolor(gs10)) ytitle(Effect of welfare expansion treatment on vote likelihood) ylabel(-2(1)2) ymtick(-2(.5)2) xtitle("") xlabel(1 4 7, labsize(medsmall)) xtick(1(1)7) graphregion(margin(l+8 r+8)) recast(line) recastci(rarea) ci1opts(fcolor(%30)) ci2opts(fcolor(%30)) title("") legend(pos(6) ring(0)) saving(Figures/pid7.gph, replace)

reg votelikely i.expansion##i.tightening##c.anti_immig_scale, robust
est sto anti_immig_scale
margins, dydx(expansion) over(tightening) at(anti_immig_scale=(0(1)4))
marginsplot, yline(0, lpattern(dot) lcolor(gs10)) ytitle(Effect of welfare expansion treatment on vote likelihood) ylabel(-2(1)2) ymtick(-2(.5)2) graphregion(margin(l+8 r+8)) recast(line) recastci(rarea) ci1opts(fcolor(%30)) ci2opts(fcolor(%30)) title("") legend(pos(6) ring(0)) saving(Figures/anti_immig_scale.gph, replace)

esttab pid7 anti_immig_scale using Tables/pid7_anti_immig, b(2) se(2) onecell star(* .1 ** .05 *** .01) r2 tab label interaction(" X ") nomtitles nobaselevels replace /*Table D4*/

grc1leg Figures/pid7.gph Figures/anti_immig_scale.gph
gr export Figures/pid7_anti_immig_scale.png, as(png) replace /*Figure D4*/

*Geographic context - % foreign born in ZIP code - 2022 and change from 2018-2022
reg votelikely i.expansion##i.tightening##c.ZIP_pctforeign_22, robust
est sto zipforeign
margins, dydx(expansion) over(tightening) at(ZIP_pctforeign_22=(0(5)40)) /*1st to 95th percentile values*/
marginsplot, yline(0, lpattern(dot) lcolor(gs10)) ytitle(Effect of welfare expansion treatment on vote likelihood) ylabel(-2(1)2) ymtick(-2(.5)2) xlabel(0(10)40, labsize(medsmall)) graphregion(margin(l+8 r+8)) recast(line) recastci(rarea) ci1opts(fcolor(%30)) ci2opts(fcolor(%30)) title("") legend(pos(6) ring(0)) saving(Figures/zipforeign.gph, replace)

reg votelikely i.expansion##i.tightening##c.ZIP_pctforeign_18to22, robust
est sto zipforeignchange
margins, dydx(expansion) over(tightening) at(ZIP_pctforeign_18to22=(-3.5(.5)4)) /*5th to 95th percentile values*/
marginsplot, yline(0, lpattern(dot) lcolor(gs10)) ytitle(Effect of welfare expansion treatment on vote likelihood) ylabel(-2(1)2) ymtick(-2(.5)2) xlabel(-3(1)4, labsize(medsmall)) graphregion(margin(l+8 r+8)) recast(line) recastci(rarea) ci1opts(fcolor(%30)) ci2opts(fcolor(%30)) title("") legend(pos(6) ring(0)) saving(Figures/zipforeignchange.gph, replace)
graph export Figures/zipforeignchange.png, as(png) replace

esttab zipforeign zipforeignchange using Tables/zipforeign, b(2) se(2) onecell star(* .1 ** .05 *** .01) r2 tab label interaction(" X ") nomtitles nobaselevels replace /*Table D5*/

grc1leg Figures/zipforeign.gph Figures/zipforeignchange.gph
gr export Figures/zipforeign_zipforeignchange.png, as(png) replace /*Figure D5*/

//Appendix E. Descriptive Analysis of Explicit Welfare Chauvinism Question Response.

*Overall frequency distribution
mlogit wc_explicit
margins
marginsplot, recast(scatter) xlabel(1 "General support" 2 "General opposition" 3 "Exclude all immigrants" 4 "Exclude undocumented", labsize(medsmall) angle(45)) xtitle("") xscale(r(.75 4.25)) ytitle("Proportion") ylabel(0(.1).5) title("")
gr export Figures/explicit_desc.png, as(png) replace /*Figure E1*/

*Correlates of responses to explicit welfare chauvinism question
global graphlist
foreach v of varlist pid7_clean ideology anti_immig_scale3 imm3 race4 educ polknow3 faminc_3 age_3 woman{
	qui sum `v'
	local xright=r(max)+.25
	local xleft=r(min)-.25
	mlogit wc_explicit i.`v', baseoutcome(2)
	qui margins, over(`v')
	marginsplot, title("") xlabel(, labsize(small)) ylabel(0(.2).8) ///
	legend(order(5 "General support" 6 "General opposition" ///
	7 "Exclude all immigrants" 8 "Exclude undocumented immigrants")) ///
	xscale(r(`xleft' `xright')) saving(Figures/explicit_`v', replace)
	global graphlist $graphlist Figures/explicit_`v'.gph
}

grc1leg Figures/explicit_educ.gph Figures/explicit_polknow3.gph Figures/explicit_pid7_clean.gph Figures/explicit_ideology.gph
gr export Figures/explicit_keyvars.png, as(png) replace /*Figure E2*/

grc1leg Figures/explicit_race4.gph Figures/explicit_imm3.gph Figures/explicit_anti_immig_scale3.gph, row(1) saving(Figures/explicit_partial1.gph, replace) 
grc1leg Figures/explicit_age_3.gph Figures/explicit_woman.gph, row(1) graphregion(margin(r+30 l+30)) saving(Figures/explicit_partial2.gph, replace) 
grc1leg Figures/explicit_partial1.gph Figures/explicit_partial2.gph, row(2)
gr export Figures/explicit_other.png, as(png) replace /*Figure E3*/
erase "Figures/explicit_partial1.gph" 
erase "Figures/explicit_partial2.gph"

//Appendix F. Analysis of Respondent Guesses of Candidate Partisanship.
reg wc_partyguess i.wctreat
margins, over(wctreat)
marginsplot, recast(scatter) title("") ylabel(0(.2)1) ymtick(0(.1)1) xscale(r(.6 4.4)) xtitle("") ytitle(Predicted probability of guessing Republican)
graph export Figures/wc_partyguess.png, as(png) replace /*Figure F1*/

//Appendix B. Descriptive statistics
dtable votelikely ideology educ faminc_clean polknow pid7_clean anti_immig_scale age i.race4 i.woman i.imm3, nformat(%9.3g) export(Tables/descriptive.docx, replace) /*Table B1*/

tab wctreat, sum(votelikely) /*Table B2*/

//Calculations for Bayes factor - most of BF analysis done in R
tab wctreat, sum(votelikely) 
mean votelikely, over(wctreat)
lincom _b[c.votelikely@1.wctreat] - _b[c.votelikely@3.wctreat] /*Difference = .3992368, SE=.1015799, t=3.93, n1=246, n2=245*/
lincom _b[c.votelikely@4.wctreat] - _b[c.votelikely@3.wctreat] /*Difference = .0632253, SE=.111641, t=0.57, n1=255, n2=245*/

log close
exit
